# -*- coding: utf-8 -*-
import glob
import random
from os import path

import numpy as np
from PIL import Image, ImageOps

# 画廊，1表示放置一个图片，0表示留空
SHAPE_FRAME = [
    [0, 0, 1, 1, 0, 1, 1, 0, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 1, 1, 1, 1, 1, 0, 0],
    [0, 0, 0, 1, 1, 1, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0, 0, 0],
]

# 每张图片的大小
BLOCK_WIDTH = 50
BLOCK_HEIGHT = 50

# 保持纵横比
PRESERVE_ASPECT_RATIO = False

# 图片边框宽度
BLOCK_BORDER_WIDTH = 2

# 边框颜色
BLOCK_BORDER_COLOR = (255, 255, 255)

# 背景颜色
GALLERY_BACKGROUND_COLOR = (255, 192, 203)

# 随机旋转小图的角度：最小值，最大值
# (0, 0) 表示不旋转
ROTATION_ANGLES = (0, 0)


def add_img_border(src: Image.Image, bor_width=3, color=(0, 0, 0)):
    """ 图片添加边框 """
    w, h = src.size[0] + 2 * bor_width, src.size[1] + 2 * bor_width
    new_img = Image.new(mode='RGB', size=(w, h), color=color)
    new_img.paste(src, (bor_width, bor_width))
    return new_img


def resize(src: Image.Image, max_w, max_h) -> Image.Image:
    """ 缩小图片的大小 """
    if PRESERVE_ASPECT_RATIO:
        src.thumbnail((max_w, max_h), Image.ANTIALIAS)  # 会保持比例
        return src
    else:
        img = src.resize((max_w, max_h), Image.ANTIALIAS)
        return img


def fill_gallery_block(x, y, img_file: str, gallery: Image.Image):
    """ 填充格子 """
    pos_x = x * BLOCK_WIDTH if x > 0 else BLOCK_BORDER_WIDTH  # 填充起始X坐标位置
    pos_y = y * BLOCK_HEIGHT if y > 0 else BLOCK_BORDER_WIDTH  # 填充起始Y坐标位置

    img = Image.open(img_file)
    img = ImageOps.exif_transpose(img)  # 根据exif信息自动调整方向
    img = img.rotate(random.uniform(ROTATION_ANGLES[0], ROTATION_ANGLES[1]), fillcolor=BLOCK_BORDER_COLOR)
    img = resize(img, BLOCK_WIDTH - BLOCK_BORDER_WIDTH, BLOCK_HEIGHT - BLOCK_BORDER_WIDTH)

    if BLOCK_BORDER_WIDTH > 0:  # 添加边框
        img = add_img_border(img, bor_width=BLOCK_BORDER_WIDTH, color=BLOCK_BORDER_COLOR)

    gallery.paste(img, (pos_x, pos_y))


if __name__ == '__main__':
    # 读取图片文件列表
    image_files = []
    for f in glob.glob("./images/*.jpg"):  # windows 会忽略文件名大小写
        image_files.append(path.abspath(f))
    random.shuffle(image_files)  # 打乱顺序

    # 创建画廊
    width = np.shape(SHAPE_FRAME)[1] * BLOCK_WIDTH + BLOCK_BORDER_WIDTH * 2  # 照片墙宽度
    height = np.shape(SHAPE_FRAME)[0] * BLOCK_HEIGHT + BLOCK_BORDER_WIDTH * 2  # 照片墙高度
    gallery = Image.new(mode='RGB', size=(width, height), color=GALLERY_BACKGROUND_COLOR)

    print("INFO: 图片文件的数量为 {0}，画廊中的格子数为 {1}".format(len(image_files), np.sum(SHAPE_FRAME)))
    if len(image_files) < np.sum(SHAPE_FRAME):
        print("ERR: 图片文件数量少于画廊中的格子数")
        exit(1)

    # 填充格子
    img_idx = 0
    for y in range(np.shape(SHAPE_FRAME)[0]):
        for x in range(np.shape(SHAPE_FRAME)[1]):
            if SHAPE_FRAME[y][x] == 1:
                fill_gallery_block(x, y, image_files[img_idx], gallery)
                img_idx += 1

    gallery.save('./shape_gallery.jpg')
    print("INFO: 已经完成")
